package com.tarena.lbs.business.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tarena.lbs.attach.api.AttachApi;
import com.tarena.lbs.attach.pojo.param.PicUpdateParam;
import com.tarena.lbs.base.common.utils.Asserts;
import com.tarena.lbs.base.protocol.exception.BusinessException;
import com.tarena.lbs.base.protocol.pager.PageResult;
import com.tarena.lbs.business.dao.repository.BusinessRepository;
import com.tarena.lbs.business.dao.repository.StoreESRepository;
import com.tarena.lbs.business.dao.repository.StoreRepository;
import com.tarena.lbs.business.pojo.param.StoreParam;
import com.tarena.lbs.business.pojo.po.BusinessPO;
import com.tarena.lbs.business.pojo.po.StorePO;
import com.tarena.lbs.business.pojo.po.StoreSearchPO;
import com.tarena.lbs.business.pojo.query.AreaStoreQuery;
import com.tarena.lbs.business.pojo.query.StoreQuery;
import com.tarena.lbs.business.pojo.vo.StoreVO;
import com.tarena.lbs.business.service.StoreService;
import com.tarena.lbs.common.enums.Roles;
import com.tarena.lbs.common.principle.UserPrinciple;
import com.tarena.lbs.common.utils.AuthenticationContextUtils;
import com.tarena.lbs.user.api.UserApi;
import com.tarena.lbs.user.api.pojo.dto.AdminDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.baomidou.mybatisplus.core.toolkit.Wrappers.lambdaQuery;

@Slf4j
@RequiredArgsConstructor
@Service
public class StoreServiceImpl implements StoreService {
    private final StoreRepository storeRepository;
    private final BusinessRepository businessRepository;
    private final StoreESRepository storeESRepository;
    private final RedisGeoService redisGeoService;
    @DubboReference
    private UserApi userApi;
    @DubboReference
    private AttachApi attachApi;
    /*店铺分页查询*/
    @Override
    public PageResult<StoreVO> storeList(StoreQuery storeQuery) throws BusinessException {
        // 检查用户登录状态
        UserPrinciple userPrinciple = AuthenticationContextUtils.get();
        Asserts.isTrue(userPrinciple == null, new BusinessException("-2", "用户未登录，请先登录"));
        // 获取用户角色
        Roles userRole = userPrinciple.getRole();
        if (Roles.SHOP.equals(userRole)) {
            // 调用用户服务获取商家信息
            AdminDto adminDto = userApi.getAdminById(userPrinciple.getId());
            Asserts.isTrue(adminDto == null, new BusinessException("-3", "商家信息为空，请检查"));
            // 增加商家 id 的查询条件
            storeQuery.setBusinessId(adminDto.getBusinessId());
        }
        //创建分页对象
        Page<StorePO> page = new Page<>(storeQuery.getPageNo(), storeQuery.getPageSize());
        //调用repository获取分页数据
        Page<StorePO> storePOPage = storeRepository.getStorePageList(storeQuery, page);
        // 将 PO 转换为 VO
        List<StoreVO> storeVOList = storePOPage.getRecords().stream()
                .map(storePO -> {
                    StoreVO storeVO = new StoreVO();
                    org.springframework.beans.BeanUtils.copyProperties(storePO, storeVO);
                    return storeVO;
                })
                .collect(Collectors.toList());
        // 封装分页结果
        PageResult<StoreVO> pageResult = new PageResult<>();
        pageResult.setTotal(storePOPage.getTotal());
        pageResult.setPageNo(storeQuery.getPageNo());
        pageResult.setPageSize(storeQuery.getPageSize());
        pageResult.setObjects(storeVOList);

        return pageResult;
    }
    /*店铺新增*/
    @Override
    public void saveStore(StoreParam param) throws BusinessException {
        //效验登录状态
        UserPrinciple userPrinciple = AuthenticationContextUtils.get();
        Asserts.isTrue(userPrinciple == null, new BusinessException("-2", "用户未登录，请先登录"));
        //获取当前用户角色，判断是否是商家
        Roles userRole = userPrinciple.getRole();
        Asserts.isTrue(!Roles.SHOP.equals(userRole), new BusinessException("-3", "只有商家才能新增店铺"));
        //检测商家是否存在
        Integer businessId = param.getBusinessId();
        BusinessPO businessPO = businessRepository.selectOne(
                lambdaQuery(BusinessPO.class)
                        .eq(BusinessPO::getId, businessId)
        );
        Asserts.isTrue(businessPO == null, new BusinessException("-4", "商家不存在"));
        //新增店铺功能
        StorePO po =new StorePO();
        BeanUtils.copyProperties(param, po);
        storeRepository.save(po);
        //保存数据到Elasticsearch
        StoreSearchPO storeSearchPO = new StoreSearchPO();
        storeSearchPO.setId(po.getId());
        storeSearchPO.setStoreName(po.getStoreName());
        storeSearchPO.setBusinessId(po.getBusinessId());
        storeSearchPO.setGeoPoint(po.getStoreLatitude(), po.getStoreLongitude());
        storeESRepository.save(storeSearchPO);
        // 将店铺位置信息保存到 Redis GEO
        try {
            double longitude = Double.parseDouble(po.getStoreLongitude());
            double latitude = Double.parseDouble(po.getStoreLatitude());
            String member = String.valueOf(po.getId());
            redisGeoService.addStoreLocation("store_locations", longitude, latitude, member);
        } catch (NumberFormatException e) {
            log.error("店铺位置信息转换失败，店铺 ID: {}", po.getId(), e);
        }
        //绑定图片信息
        if (param.getStoreImagesIds() != null && !param.getStoreImagesIds().isEmpty( )){
                List<PicUpdateParam> picParams =new ArrayList<>();
                for (String fileUuid : param.getStoreImagesIds()) {
                    PicUpdateParam picUpdateParam =new PicUpdateParam();
                    picUpdateParam.setFileUuid(fileUuid);
                    picUpdateParam.setBusinessId(po.getId());
                    picUpdateParam.setBusinessType(1);
                    picParams.add(picUpdateParam);
                }
            boolean result = attachApi.batchUpdateBusiness(picParams);
            if (!result) {
                throw new BusinessException("-5", "绑定图片信息失败");
            }
        }
    }
    /*查询区域下的店铺列表*/

    @Override
    public PageResult<StoreVO> getStoreByCity(AreaStoreQuery query) throws BusinessException {
        // 检查登录状态
        UserPrinciple userPrinciple = AuthenticationContextUtils.get();
        Asserts.isTrue(userPrinciple == null, new BusinessException("-2", "用户未登录，请先登录"));

        // 获取商家账号信息
        Integer adminId = userPrinciple.getId();
        AdminDto adminDto = userApi.getAdminById(adminId);
        Asserts.isTrue(adminDto == null, new BusinessException("-3", "商家信息为空，请检查"));
        Integer businessId = adminDto.getBusinessId();

        // 创建分页对象
        Page<StorePO> page = new Page<>(query.getPageNo(), query.getPageSize());

        // 调用 repository 进行分页查询
        Page<StorePO> storePOPage = storeRepository.getStoreByCityAndBusinessId(query.getCityIdList(), businessId, page);

        // 将 PO 转换为 VO
        List<StoreVO> storeVOList = storePOPage.getRecords().stream()
                .map(storePO -> {
                    StoreVO storeVO = new StoreVO();
                    org.springframework.beans.BeanUtils.copyProperties(storePO, storeVO);
                    return storeVO;
                })
                .collect(Collectors.toList());

        // 封装分页结果
        PageResult<StoreVO> pageResult = new PageResult<>();
        pageResult.setTotal(storePOPage.getTotal());
        pageResult.setPageNo(query.getPageNo());
        pageResult.setPageSize(query.getPageSize());
        pageResult.setObjects(storeVOList);

        return pageResult;
    }
}
